package com.nativetalk.service.four.reserve.insert;

import com.nativetalk.base.Page;
import com.nativetalk.base.RetInfo;
import com.nativetalk.bean.course.TsNtCourseInfoDetail;
import com.nativetalk.bean.live.TdNtLiveCourseHisDetail;
import com.nativetalk.bean.member.TdNtMember;
import com.nativetalk.bean.member.course.TdNtMembCourseSize;
import com.nativetalk.bean.member.setmeal.TdNtMembSetmealDetail;
import com.nativetalk.bean.reserve.TdNtReserveInsert;
import com.nativetalk.bean.reserve.TdNtReserveMemberList;
import com.nativetalk.bean.reserve.TdNtReserveTimeDetail;
import com.nativetalk.bean.teacher.TdNtTeacherIndex;
import com.nativetalk.bean.teacher.TdNtTeacherTuisong;
import com.nativetalk.bean.website.TsNtWebSiteConfIndex;
import com.nativetalk.common.Constants;
import com.nativetalk.common.ValidationMessages;
import com.nativetalk.common.getui.AndroidReserveTeacher;
import com.nativetalk.common.getui.IosReserveTeacher;
import com.nativetalk.common.util.*;
import com.nativetalk.dao.*;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.collections.map.HashedMap;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.BufferedWriter;
import java.io.File;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by wangzheng on 2017/2/17.
 */
@Service
public class FourReserveInsertServiceImpl implements FourReserveInsertService {
    private static Logger logger = Logger.getLogger(FourReserveInsertServiceImpl.class);
    @Resource
    private TdNtReserveDao tdNtReserveDao;
    @Resource
    private TdNtTeacherDao tdNtTeacherDao;
    @Resource
    private TdNtLiveCourseHisDao tdNtLiveCourseHisDao;
    @Resource
    private TdNtMembCourseSizeDao tdNtMembCourseSizeDao;
//    @Resource
//    private TdNtBookCourseDao tdNtBookCourseDao;
    @Resource
    private TdNtMembSetmealDao tdNtMembSetmealDao;
    @Resource
    private TdNtReserveTimeDao tdNtReserveTimeDao;

    @Override
    @Transactional
    public synchronized RetInfo addTdNtReserveInsert(TdNtReserveInsert tdNtReserveInsert, TdNtMember tdNtMember) {
        String logInfo = this.getClass().getName() + ":addTdNtReserveInsert:";
        // 类路径+方法名
        logger.info("======" + logInfo + "begin======");
        RetInfo retInfo = new RetInfo();
        try {
            /**
             * 查找该老师是否有冲突时间的预约课或直播课
             */
            Map<String, Object> map = new HashMap<>();
            map.put("tea_id", tdNtReserveInsert.getTea_id());
            map.put("start_time", tdNtReserveInsert.getReserve_start_time());
            map.put("end_time", tdNtReserveInsert.getReserve_end_time());
            TdNtReserveInsert tdNtReserve = tdNtReserveDao.findTdNtReserverConflict(map);
            if (tdNtReserve != null) {
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("该老师该时间已被预约,请预约其他时间");
                return retInfo;
            } else {
                TdNtLiveCourseHisDetail live = tdNtLiveCourseHisDao.findTdNtLiveCourseHisDetailConflict(map);
                if (live != null) {
                    retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                    retInfo.setTip("该老师该时间已被预约,请预约其他时间");
                    return retInfo;
                }
            }

            // 查询购买的课程的剩余课时
            int memb_id = tdNtReserveInsert.getMemb_id();
            int cou_id = tdNtReserveInsert.getCou_id();
            Map<String, Object> mapParm = new HashMap<>();
            mapParm.put("memb_id", memb_id);
            mapParm.put("cou_id", cou_id);
            TdNtMembCourseSize tdNtMembCourseSize = tdNtMembCourseSizeDao.findTdNtMembCourseSizeByMembIdAndCouId(mapParm);
            if (null != tdNtMembCourseSize && 0 < tdNtMembCourseSize.getCou_size()) {
                /**
                 * 判断学生在当前时间段内是否预约了其他老师
                 */
                map.put("memb_id", tdNtReserveInsert.getMemb_id());
                TdNtReserveInsert tdNtReserve1 = tdNtReserveDao.findTdNtMemberReserveConflict(map);
                if (tdNtReserve1 != null) {
                    retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                    retInfo.setTip("该时间已预约其他老师,请预约其他时间");
                    return retInfo;
                }

                /**
                 * 查找用户购买该课程的失效日期最早的规格套餐（因为一门课学生可以买多次，即将过期的套餐优先预约）
                 */
                Map<String, Object> map3 = new HashMap<>();
                map3.put("memb_id", tdNtReserveInsert.getMemb_id());
                map3.put("cou_id", tdNtReserveInsert.getCou_id());
                TdNtMembSetmealDetail tdNtMembSetmealDetail = tdNtMembSetmealDao.findTdNtMembSetmealDetailEndByMembIdAndCouId(map3);

                /**
                 * 插入一条预约的信息
                 */
                tdNtReserveInsert.setReserve_time(50);//单位为分钟
                tdNtReserveInsert.setState(Constants.ReserveState.ready_to_begin);//待上课
                tdNtReserveInsert.setType(Constants.ReserveType.setmeal_course);//类型为购买课程预约
                tdNtReserveInsert.setMemb_set_id(tdNtMembSetmealDetail.getMemb_set_id());
                tdNtReserveDao.insertTdNtReserve(tdNtReserveInsert);

                /**
                 * 更新用户购买该课程的失效日期最早的规格套餐的剩余预约次数
                 */
                Map<String, Object> map4 = new HashMap<>();
                map4.put("memb_set_id",tdNtMembSetmealDetail.getMemb_set_id());
                map4.put("set_reserve_size", tdNtMembSetmealDetail.getSet_reserve_size() - 1);//剩余预约次数
                tdNtMembSetmealDao.updateTdNtMembSetmealDetailEnd(map4);

                /**
                 * 更新购买课程的总剩余预约次数
                 */
                tdNtMembCourseSize.setCou_size((tdNtMembCourseSize.getCou_size() - 1));
                tdNtMembCourseSizeDao.updateTdNtMembCourseSizeByMembIdAndCouId(tdNtMembCourseSize);

                /**
                 * 更新老师端开通的时间状态变为已预约
                 */
                Date date1 = new Date(tdNtReserveInsert.getReserve_start_time().getTime());
                TdNtReserveTimeDetail tdNtReserveTimeDetail = new TdNtReserveTimeDetail();
                tdNtReserveTimeDetail.setReserve_time(CommonUtil.getHour(date1));
                tdNtReserveTimeDetail.setTea_id(tdNtReserveInsert.getTea_id());
                tdNtReserveTimeDetail.setDate(date1);
                tdNtReserveTimeDetail.setIs_valid(Constants.ReserveTimeState.booked);
                tdNtReserveTimeDao.updateTdNtReserveTimeSetIsValid(tdNtReserveTimeDetail);

                /**
                 * 创建教室
                 */
                Map<String, Object> map5 = new HashMap<>();
                map5.put("reserve_id", tdNtReserveInsert.getReserve_id());
                map5.put("tea_id", tdNtReserveInsert.getTea_id());
                map5.put("memb_id", tdNtReserveInsert.getMemb_id());
                map5.put("cou_id", tdNtReserveInsert.getCou_id());
                map5.put("set_id", tdNtReserveInsert.getMemb_set_id());
                map5.put("room_state", Constants.RoomState.close);
                map5.put("room_create_date", new Date());
                map5.put("room_open_date", DateUtil.addMinute(tdNtReserveInsert.getReserve_start_time(), -10));
                map5.put("room_close_date", DateUtil.addMinute(tdNtReserveInsert.getReserve_end_time(), 30));
                tdNtReserveTimeDao.createClassRoom(map5);


                retInfo.setMark(ValidationMessages.getValue("MARKYES"));
                retInfo.setTip("预约成功");

                /**
                 * 给教师发推送及邮件
                 */
                TdNtTeacherTuisong tdNtTeacherTuisong = tdNtTeacherDao.findTdNtTeacherTuisong(tdNtReserveInsert.getTea_id());
                if (tdNtTeacherTuisong.getEqu_client_id() != null && !(tdNtTeacherTuisong.getEqu_client_id().equals(Constants.default_equ_id))) {
                    /**
                     * 发推送
                     */
                    if (tdNtTeacherTuisong.getEqu_type().equals(Constants.equ_type_android)) {
                        AndroidReserveTeacher.apnpush("NativeTalk", "Dear NativeTalk tutor, new assignment class, please check the time for the class.\n ",
                                tdNtTeacherTuisong.getEqu_client_id(), tdNtReserveInsert.getReserve_id());
                    } else {
                        logger.info(tdNtTeacherTuisong.getEqu_client_id());
                        IosReserveTeacher.apnpush("NativeTalk", "Dear NativeTalk tutor, new assignment class, please check the time for the class.\n ",
                                tdNtTeacherTuisong.getEqu_client_id(), tdNtReserveInsert.getReserve_id());

                    }

                    // 发送邮件
                    // 处理html邮件模板
                    //教学费用 老师每分钟0.2美分
                    //从缓存中读取老师每分钟的教学费用
                    Map<String, TsNtWebSiteConfIndex> tsNtWebSiteConfIndexMap = (Map<String, TsNtWebSiteConfIndex>) MemcachedUtils.get(MemcachedKey.tsNtWebSiteConfIndexMap);
                    //教学费用 老师每分钟0.2美分
                    BigDecimal tea_amount = new BigDecimal(tsNtWebSiteConfIndexMap.get("24").getData_value());//0.2
                    int courseDuration = tdNtReserveInsert.getReserve_time();//预约的课程的上课时长
                    BigDecimal earnMoney = tea_amount.multiply(new BigDecimal(courseDuration));//老师上完课应该赚取多少钱 = 每分钟单价 X 课程的时长（分钟）

                    Map<String, TsNtCourseInfoDetail> courseMap = (Map<String, TsNtCourseInfoDetail>) MemcachedUtils.get(MemcachedKey.tsNtCourseInfoDetailMap);
                    TsNtCourseInfoDetail course = courseMap.get(cou_id + "");

                    // freemarker的model(数据模型)
                    Map<String, Object> ftlModel = new HashedMap();
                    ftlModel.put("tea_name", tdNtTeacherTuisong.getTea_name());
                    ftlModel.put("memb_name", tdNtMember.getMemb_name());
                    ftlModel.put("course_name", course.getCou_english_name());
                    ftlModel.put("start_time", DateUtil.format(tdNtReserveInsert.getReserve_end_time(), "MM-dd HH:mm"));
                    ftlModel.put("money", earnMoney.doubleValue());

                    // freemarker 初始化
                    Configuration cfg = Configuration.getDefaultConfiguration();
                    String path = this.getClass().getResource("/").getPath() + "email/";
                    cfg.setDirectoryForTemplateLoading(new File(path));
                    cfg.setDefaultEncoding("utf-8");
                    Template temp = cfg.getTemplate("teacher_course_notify.ftl", "UTF-8");
                    StringWriter stringWriter = new StringWriter();
                    BufferedWriter bufferedWriter = new BufferedWriter(stringWriter);
                    temp.process(ftlModel, stringWriter);

                    String toEmail = tdNtTeacherTuisong.getTea_email();//收件人邮箱
                    String subject = "[NativeTalk] New Appointment";//邮件标题
                    String htmlContent = stringWriter.toString();//邮件内容

                    SendMailUtil.sendMail(toEmail, subject, htmlContent);// 发送邮件

                }
            }
            else{
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("该课程您未购买或可预约的次数已用完");
            }

        } catch (Exception e) {
            retInfo.setMark(ValidationMessages.getValue("MARKERROR"));
            retInfo.setTip(ValidationMessages.getValue("TIPERROR"));
            logger.error(e.getMessage(), e);
        }
        logger.info("======" + logInfo + "end======");
        return retInfo;
    }

    @Override
    public RetInfo findTdNtReserveCanCancelUnFinishByMembId(Page page) {
        String logInfo = this.getClass().getName() + ":findTdNtReserveCanCancelUnFinishByMembId:";
        // 类路径+方法名
        logger.info("======" + logInfo + "begin======");
        RetInfo retInfo = new RetInfo();
        try {
            Map<String, TsNtCourseInfoDetail> tsNtCourseInfoDetailMap = (Map<String, TsNtCourseInfoDetail>) MemcachedUtils.get(MemcachedKey.tsNtCourseInfoDetailMap);

            int totalPage;//总页数
            int currentPage = page.getCurrentPage();
            int pageSize = page.getPageSize();
            int totalRecord = tdNtReserveDao.findTdNtReserverByUnFinishMembId(page);//总条数
            if (totalRecord % pageSize == 0) {
                totalPage = totalRecord / pageSize;
            } else {
                totalPage = (totalRecord / pageSize) + 1;
            }
            if (currentPage >= totalPage) {
                currentPage = totalPage;
            }
            if (currentPage <= 1) {
                currentPage = 1;
            }
            page.setCurrentPage((currentPage - 1) * 10);

            List<TdNtReserveMemberList> reserveMemberLists = tdNtReserveDao.findTdNtReserverByUnFinishMembIdPage(page);
            Iterator<TdNtReserveMemberList> iter = reserveMemberLists.iterator();
            while (iter.hasNext()) {
                TdNtReserveMemberList tdNtReserveMemberList = iter.next();
                /**
                 * 预约开始时间是否大于等于1小时
                 */
                if (!CommonUtil.getTimeCancle(tdNtReserveMemberList.getReserve_start_time())) {
                    iter.remove();
                }
            }
            if (reserveMemberLists == null || reserveMemberLists.size() <= 0) {
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("没有可取消的未完成预约订单");
            } else {
                for (int i = 0; i < reserveMemberLists.size(); i++) {
                    TdNtTeacherIndex index = tdNtTeacherDao.findTdNtTeacherIndex(reserveMemberLists.get(i).getTea_id());
                    reserveMemberLists.get(i).setTea_name(index.getTea_name());
                    reserveMemberLists.get(i).setHead_portrait(index.getTea_head_portrait());
                    if (reserveMemberLists.get(i).getCou_id() != 100) {
                        reserveMemberLists.get(i).setCou_name(
                                tsNtCourseInfoDetailMap.get(reserveMemberLists.get(i).getCou_id() + "").getCou_name());
                    } else {
                        reserveMemberLists.get(i).setCou_name("自由话题");
                    }
                }
                Map<String, Object> result = new HashMap<>();
                result.put("reserveList", reserveMemberLists);
                result.put("totalPage", totalPage);

                retInfo.setObj(result);
                retInfo.setMark(ValidationMessages.getValue("MARKYES"));
                retInfo.setTip("获取可取消的未完成预约订单成功");
            }

        } catch (Exception e) {
            retInfo.setMark(ValidationMessages.getValue("MARKERROR"));
            retInfo.setTip(ValidationMessages.getValue("TIPERROR"));
            logger.error(e.getMessage(), e);
        }
        logger.info("======" + logInfo + "end======");
        return retInfo;
    }
}
